package com.github.xiaoy.aop;


import com.github.xiaoy.DataSource;
import com.github.xiaoy.DataSourceRoutingKeyHolder;
import com.github.xiaoy.MultiDbConnectionConfig;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Core Interceptor of Dynamic Datasource
 *
 * @author songxiaoyue
 */
public class DynamicDataSourceAnnotationInterceptor implements MethodInterceptor {

    private MultiDbConnectionConfig dbConnConfig;

    public DynamicDataSourceAnnotationInterceptor(MultiDbConnectionConfig dbConnConfig) {
        this.dbConnConfig = dbConnConfig;
    }

    public MultiDbConnectionConfig getDbConnConfig() {
        return dbConnConfig;
    }

    public void setDbConnConfig(MultiDbConnectionConfig dbConnConfig) {
        this.dbConnConfig = dbConnConfig;
    }

    public static DynamicDataSourceClassResolver getRESOLVER() {
        return RESOLVER;
    }

    private static final DynamicDataSourceClassResolver RESOLVER = new DynamicDataSourceClassResolver();

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        try {
            DataSourceRoutingKeyHolder.set(determineDatasource(invocation));
            return invocation.proceed();
        } finally {
            DataSourceRoutingKeyHolder.clear();
        }
    }

    private String determineDatasource(MethodInvocation invocation) throws Throwable {
        Method method = invocation.getMethod();
//        DataSource ds = method.isAnnotationPresent(DataSource.class)
//                ? method.getAnnotation(DataSource.class)
//                : AnnotationUtils.findAnnotation(RESOLVER.targetClass(invocation), DataSource.class);

        Map<String, String> locationMap = dbConnConfig.getList()
                .stream()
                .collect(Collectors.toMap(MultiDbConnectionConfig.ConnectionInfo::getLocation, MultiDbConnectionConfig.ConnectionInfo::getName));
        String key = null;
//        if (Objects.nonNull(ds)) {
//            key = ds.value();
//        } else {
//
//        }
        String name = method.getDeclaringClass().getPackage().getName();

        if (locationMap.containsKey(name)) {
            key =  locationMap.get(name);
        }
        return key;
    }
}
